﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;

namespace YJKDragCurveJig
{
	public class JigFamilyCreator
	{
		public string SymbolName
		{
			get
			{
				return this.m_SymbolName;
			}
		}

        public JigFamilyCreator(ExternalCommandData commandData, Autodesk.Revit.DB.Document familyDocument)
		{
			this.m_Revit = commandData;
			this.m_FamilyDocument = familyDocument;
		}

		public Result CreateJIGFamily(List<JigEdgeInfo> curveInfoList, List<JigTextInfo> textInfoList, XYZ ptBase, ref string message)
		{
			Result result = Result.Failed;
			View view = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_FamilyDocument);
			filteredElementCollector.OfClass(typeof(ViewSheet));
			FilteredElementIterator elementIterator = filteredElementCollector.GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				ViewSheet viewSheet = element as ViewSheet;
				if (viewSheet != null && viewSheet.Name.CompareTo("图纸") == 0)
				{
					view = viewSheet;
					break;
				}
			}
			if (view == null)
			{
				return result;
			}
			Transaction transaction = new Transaction(this.m_FamilyDocument);
			transaction.Start("create family");
			Transform transform = RevitVersionFuncs.CreateTranslation(-ptBase);
			Transform identity = Transform.Identity;
			int scale = this.m_Revit.Application.ActiveUIDocument.ActiveView.Scale;
			Transform transform2 = identity.ScaleBasis(1.0 / (double)scale);
			transform2 = transform2.Multiply(transform);
			this.CreateCurve(curveInfoList, transform2, view);
			this.GreateText(textInfoList, transform2, view);
			this.AddSymbols(ref this.m_SymbolName, ref message);
			transaction.Commit();
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private void CreateCurve(List<JigEdgeInfo> curveInfoList, Transform tran, View mainView)
		{
			CurveArray curveArray = new CurveArray();
			Application create = this.m_Revit.Application.Application.Create;
			foreach (JigEdgeInfo jigEdgeInfo in curveInfoList)
			{
				try
				{
					XYZ xyz = this.Get2DXYZ(jigEdgeInfo.StartPoint);
					XYZ xyz2 = this.Get2DXYZ(jigEdgeInfo.EndPoint);
					if (!xyz.IsAlmostEqualTo(xyz2))
					{
						XYZ xyz3 = JigGeometry.TransformPoint(xyz, tran);
						XYZ xyz4 = JigGeometry.TransformPoint(xyz2, tran);
						if (jigEdgeInfo.IsArc)
						{
							XYZ xyz5 = null;
							double num = 0.0;
							double dSAngle = 0.0;
							double dEAngle = 0.0;
							JigGeometry.GetArcInfoWithBulge(xyz3, xyz4, jigEdgeInfo.Bulge, ref xyz5, ref num, ref dSAngle, ref dEAngle);
							double angle = JigGeometry.BetweenTheAngles(dSAngle, dEAngle, true) / 2.0;
							XYZ pt = xyz3 - xyz5;
							XYZ radianPnt = xyz5 + JigGeometry.RotateTo(pt, angle, XYZ.BasisZ);
							Arc arc = this.m_Revit.Application.ActiveUIDocument.Document.CreatYJKArc(xyz3, xyz4, radianPnt);
							curveArray.Append(arc);
						}
						else
						{
							Line line = Line.CreateBound(xyz3, xyz4);
							curveArray.Append(line);
						}
					}
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
			}
			if (curveArray.Size > 0)
			{
				this.m_FamilyDocument.FamilyCreate.NewDetailCurveArray(mainView, curveArray);
			}
		}

		private void GreateText(List<JigTextInfo> textInfoList, Transform tran, View mainView)
		{
			foreach (JigTextInfo jigTextInfo in textInfoList)
			{
				try
				{
					XYZ origin = JigGeometry.TransformPoint(jigTextInfo.Origin, tran);
					XYZ baseVec = jigTextInfo.BaseVec;
					TextAlignFlags textAlign = jigTextInfo.TextAlign;
					string strText = jigTextInfo.StrText;
					double num = jigTextInfo.theTextNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble() * 100.0 * (double)mainView.Scale / 100.0;
					double num2 = jigTextInfo.theTextNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
					double num3 = num * num2;
					double lineWidth = (double)(jigTextInfo.StrText.Length * 2) * num3;
					this.m_FamilyDocument.GetTextNode(mainView, origin, baseVec, XYZ.BasisZ, lineWidth, textAlign, strText).TextNoteType = this.GetTextNoteType(jigTextInfo.theTextNoteType);
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
			}
		}

		private TextNoteType GetTextNoteType(TextNoteType oldType)
		{
			string strB = "3 mm";
			string text = oldType.Name + "_ViewScale";
			TextNoteType textNoteType = null;
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_FamilyDocument);
			filteredElementCollector.OfClass(typeof(TextNoteType));
			FilteredElementIterator elementIterator = filteredElementCollector.GetElementIterator();
			elementIterator.Reset();
			while (elementIterator.MoveNext())
			{
				Element element = elementIterator.Current;
				TextNoteType textNoteType2 = element as TextNoteType;
				if (textNoteType2 != null)
				{
					if (textNoteType2.Name.CompareTo(text) == 0)
					{
						textNoteType = textNoteType2;
						break;
					}
					if (this.m_DefaultTextNoteType == null && textNoteType2.Name.CompareTo(strB) == 0)
					{
						this.m_DefaultTextNoteType = textNoteType2;
					}
				}
			}
			if (textNoteType == null)
			{
				textNoteType = (this.m_DefaultTextNoteType.Duplicate(text) as TextNoteType);
				double num = oldType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
				textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).Set(num);
				string text2 = oldType.get_Parameter(BuiltInParameter.TEXT_FONT).AsString();
				textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).Set(text2);
				double num2 = oldType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
				textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).Set(num2);
				double num3 = oldType.get_Parameter(BuiltInParameter.TEXT_TAB_SIZE).AsDouble();
				textNoteType.get_Parameter(BuiltInParameter.TEXT_TAB_SIZE).Set(num3);
			}
			return textNoteType;
		}

		private XYZ Get2DXYZ(XYZ point3d)
		{
			return new XYZ(point3d.X, point3d.Y, 0.0);
		}

		public Result AddSymbols(ref string symbolName, ref string message)
		{
			string text = "type1";
			DisplayUnit displayUnitSystem = this.m_FamilyDocument.DisplayUnitSystem;
			try
			{
				FamilyManager familyManager = this.m_FamilyDocument.FamilyManager;
				FamilyType currentType = familyManager.NewType(text);
				familyManager.CurrentType = currentType;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				return Autodesk.Revit.UI.Result.Failed;
			}
			symbolName = text;
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private ExternalCommandData m_Revit;

        private Autodesk.Revit.DB.Document m_FamilyDocument;

		private TextNoteType m_DefaultTextNoteType;

		private string m_SymbolName = "";
	}
}
